Expand description

The OTLP Exporter supports exporting trace and metric data in the OTLP format to the OpenTelemetry collector or other compatible backend.

The OpenTelemetry Collector offers a vendor-agnostic implementation on how to receive, process, and export telemetry data. In addition, it removes the need to run, operate, and maintain multiple agents/collectors in order to support open-source telemetry data formats (e.g. Jaeger, Prometheus, etc.) sending to multiple open-source or commercial back-ends.

Currently, this crate only support sending tracing data or metrics in OTLP via grpc and http (in binary format). Supports for other format and protocol will be added in the future. The details of what’s currently offering in this crate can be found in this doc.

Quickstart

First make sure you have a running version of the opentelemetry collector you want to send data to:

$ docker run -p 4317:4317 otel/opentelemetry-collector-dev:latest

Then install a new pipeline with the recommended defaults to start exporting telemetry. You will have to build a OTLP exporter first.

Tracing and metrics pipelines can be started with new_pipeline().tracing() and new_pipeline().metrics() respectively.

use opentelemetry::trace::Tracer;

fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
    // First, create a OTLP exporter builder. Configure it as you need.
    let otlp_exporter = opentelemetry_otlp::new_exporter().tonic();
    // Then pass it into pipeline builder
    let tracer = opentelemetry_otlp::new_pipeline()
        .tracing()
        .with_exporter(otlp_exporter)
        .install_simple()?;

    tracer.in_span("doing_work", |cx| {
        // Traced app logic here...
    });

    Ok(())
}

Performance

For optimal performance, a batch exporter is recommended as the simple exporter will export each span synchronously on dropping. You can enable the [rt-tokio], [rt-tokio-current-thread] or [rt-async-std] features and specify a runtime on the pipeline builder to have a batch exporter configured for you automatically.

[dependencies]
opentelemetry_sdk = { version = "*", features = ["async-std"] }
opentelemetry-otlp = { version = "*", features = ["grpc-sys"] }
let tracer = opentelemetry_otlp::new_pipeline()
    .tracing()
    .with_exporter(opentelemetry_otlp::new_exporter().tonic())
    .install_batch(opentelemetry_sdk::runtime::AsyncStd)?;

Kitchen Sink Full Configuration

Example showing how to override all configuration options.

Generally there are two parts of configuration. One is metrics config or tracing config. Users can config it via OtlpTracePipeline or OtlpMetricPipeline. The other is exporting configuration. Users can set those configurations using OtlpExporterPipeline based on the choice of exporters.

use opentelemetry::{KeyValue, trace::Tracer};
use opentelemetry_sdk::{trace::{self, RandomIdGenerator, Sampler}, Resource};
use opentelemetry_sdk::metrics::reader::{DefaultAggregationSelector, DefaultTemporalitySelector};
use opentelemetry_otlp::{Protocol, WithExportConfig, ExportConfig};
use std::time::Duration;
use tonic::metadata::*;

fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
    let mut map = MetadataMap::with_capacity(3);

    map.insert("x-host", "example.com".parse().unwrap());
    map.insert("x-number", "123".parse().unwrap());
    map.insert_bin("trace-proto-bin", MetadataValue::from_bytes(b"[binary data]"));

    let tracer = opentelemetry_otlp::new_pipeline()
        .tracing()
        .with_exporter(
            opentelemetry_otlp::new_exporter()
            .tonic()
            .with_endpoint("http://localhost:4317")
            .with_timeout(Duration::from_secs(3))
            .with_metadata(map)
         )
        .with_trace_config(
            trace::config()
                .with_sampler(Sampler::AlwaysOn)
                .with_id_generator(RandomIdGenerator::default())
                .with_max_events_per_span(64)
                .with_max_attributes_per_span(16)
                .with_max_events_per_span(16)
                .with_resource(Resource::new(vec![KeyValue::new("service.name", "example")])),
        )
        .install_batch(opentelemetry_sdk::runtime::Tokio)?;

    let export_config = ExportConfig {
        endpoint: "http://localhost:4317".to_string(),
        timeout: Duration::from_secs(3),
        protocol: Protocol::Grpc
    };

    let meter = opentelemetry_otlp::new_pipeline()
        .metrics(opentelemetry_sdk::runtime::Tokio)
        .with_exporter(
            opentelemetry_otlp::new_exporter()
                .tonic()
                .with_export_config(export_config),
                // can also config it using with_* functions like the tracing part above.
        )
        .with_resource(Resource::new(vec![KeyValue::new("service.name", "example")]))
        .with_period(Duration::from_secs(3))
        .with_timeout(Duration::from_secs(10))
        .with_aggregation_selector(DefaultAggregationSelector::new())
        .with_temporality_selector(DefaultTemporalitySelector::new())
        .build();

    tracer.in_span("doing_work", |cx| {
        // Traced app logic here...
    });

    Ok(())
}

Grpc libraries comparison

The table below provides a short comparison between grpcio and tonic, two of the most popular grpc libraries in Rust. Users can choose between them when working with otlp and grpc.

Projecthyperium/tonictikv/grpc-rs
Feature name–features=default–features=grpc-sys
gRPC librarytonicgrpcio
Transporthyperium/hyper (Rust)grpc/grpc (C++ binding)
TLS supportyesyes
TLS optionalyesyes
TLS libraryrustlsOpenSSL
Supported .proto generatorprostprost, protobuf

Structs

Enums

Constants

Traits

Functions

  • Create a builder to build OTLP metrics exporter or tracing exporter.
  • Create a new pipeline builder with the recommended configuration.